package com.stockz.ui.swing.charting.listener;


import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.Iterator;

import com.stockz.core.util.Global;
import com.stockz.ui.swing.charting.display.Displayable;
import com.stockz.ui.swing.charting.model.Line;
import com.stockz.ui.swing.charting.model.Point;
import com.stockz.ui.swing.charting.util.RepaintStockChartPanelUtil;
import com.stockz.ui.swing.charting.util.SetStockChartPanelSizeUtil;
import com.stockz.ui.swing.charting.util.SetStockChartViewPortUtil;
import com.stockz.ui.swing.charting.util.SwingUtil;
import com.stockz.ui.swing.charting.util.UIChartingConstant;
import com.stockz.ui.swing.charting.view.StockChartPanel;
import com.stockz.ui.swing.charting.view.StockChartPanelState;
import com.stockz.ui.swing.charting.widget.EditIndicatorPopupMenu;
import com.stockz.ui.swing.charting.widget.StockChartRightClickPopupMenu;

public class StockChartPanelListener 
implements MouseListener, 
	MouseMotionListener,
	MouseWheelListener, 
	KeyListener,
	FocusListener{
	
	private Point point = new Point((StockChartPanel)Global.get(UIChartingConstant.SelectedStockChartPanel));
	private Line line = new Line((StockChartPanel)Global.get(UIChartingConstant.SelectedStockChartPanel));
	
	private StockChartRightClickPopupMenu stockChartRightClickPopupMenu = new StockChartRightClickPopupMenu();
	private EditIndicatorPopupMenu editIndicatorPopupMenu = new EditIndicatorPopupMenu();
	
	@Override
	public void keyTyped(KeyEvent e) {
		System.out.println("key typed");
	}
	
	@Override
	public void mouseDragged(MouseEvent e) {
		StockChartPanel panel = (StockChartPanel)e.getSource();
		StockChartPanelState state = panel.getStockChartPanelState();
		if(state.getDrawingRectangle().contains(e.getPoint())){
			state.setCurrentPoint(e.getPoint());
		}
		Point point = SwingUtil.unfitPoint(state, e.getPoint());
		if(this.point != null && !point.equals(this.point)){
			line.setEnd(point);
			state.getShapeSet().add(line);
			RepaintStockChartPanelUtil.repaintStockChartPanel(panel);
		}
	}
	
	@Override
	public void mouseWheelMoved(MouseWheelEvent e) {
		StockChartPanel panel = (StockChartPanel)e.getSource();
		StockChartPanelState state = panel.getStockChartPanelState();
		int space = state.getTimeUnitSpace() +  e.getWheelRotation();
		if(space > 0 && space <= 100){
			state.setTimeUnitSpace(space);
			SetStockChartPanelSizeUtil.setStockChartPanelSize(panel);
			RepaintStockChartPanelUtil.repaintStockChartPanel(panel);
		}
	}
	
	public void mousePressed(MouseEvent e) {	
		StockChartPanelState state = ((StockChartPanel)e.getSource()).getStockChartPanelState();
		Global.put(UIChartingConstant.SelectedStockChartPanel, e.getSource());
		point = SwingUtil.unfitPoint(state, e.getPoint());
		line = new Line((StockChartPanel)Global.get(UIChartingConstant.SelectedStockChartPanel));
		line.setStart(point);
	}
	
	public void mouseClicked(MouseEvent e) {	
		if(e.isConsumed()){
			return;
		}
		StockChartPanel panel = (StockChartPanel)e.getSource();
		StockChartPanelState state = panel.getStockChartPanelState();
		Global.put(UIChartingConstant.SelectedStockChartPanel, e.getSource());
		
		Iterator<? extends Displayable> iter = state.getDisplayableSet().iterator();
		while(iter.hasNext()){
			Displayable indicatorDisplay = iter.next();
			
			if(indicatorDisplay.getRemoveRectangle() != null
				&& indicatorDisplay.getRemoveRectangle().contains(e.getPoint())){
				iter.remove();
				indicatorDisplay.getRectangle().getDisplayableSet().remove(indicatorDisplay);
				RepaintStockChartPanelUtil.repaintStockChartPanel(panel);
				e.consume();
				return;
			}
			if(indicatorDisplay.getEditRectangle() != null 
				&& indicatorDisplay.getEditRectangle().contains(e.getPoint())){
				editIndicatorPopupMenu.setDisplayable(indicatorDisplay);
				editIndicatorPopupMenu.show((StockChartPanel)e.getSource(), 
						indicatorDisplay.getEditRectangle().x, indicatorDisplay.getEditRectangle().y);
				e.consume();
				return;
			}
		}
		
		 if(point != null){
			 Point end =  SwingUtil.unfitPoint(state, e.getPoint());
			 if( point.equals(end)){
				 if(e.getButton() == MouseEvent.BUTTON1){
					 if(e.isShiftDown()){
						 state.getShapeSet().add(
								 new Line(panel,
										 new Point(panel,Double.MAX_VALUE,point.getIndex()),
										 	new Point(panel,Double.MIN_VALUE,point.getIndex())));
				 }else{
					 state.getShapeSet().add(
							 new Line(panel,
									 new Point(panel,point.getPrice(),Integer.MAX_VALUE),
									 	new Point(panel,point.getPrice(),Integer.MIN_VALUE)));
				 }
				}else if(e.getButton() == MouseEvent.BUTTON3){
					stockChartRightClickPopupMenu.setPoint(SwingUtil.unfitPoint(state,e.getPoint()));
					stockChartRightClickPopupMenu.show(e.getComponent(), e.getX(), e.getY());
				}
			 }else{
				 Point p = SwingUtil.unfitPoint(state, e.getPoint());
				 state.getShapeSet().add(new Line(panel, new Point(panel,point.getPrice(),point.getIndex()),
						 											new Point(panel,p.getPrice(),p.getIndex())));
			 }
			 point = null;
			 line = null;
			 RepaintStockChartPanelUtil.repaintStockChartPanel(panel);
		 }
	}
	
	public void mouseMoved(MouseEvent e) {	
		StockChartPanel panel = (StockChartPanel)e.getSource();
		StockChartPanelState state = panel.getStockChartPanelState();
		if(state.getDrawingRectangle().contains(e.getPoint())){
			state.setCurrentPoint(e.getPoint());
		}
		RepaintStockChartPanelUtil.repaintStockChartPanel(panel);
	}
	
	@Override
	public void focusGained(FocusEvent e) {
		Global.put(UIChartingConstant.SelectedStockChartPanel, e.getSource());
	}
	
	public void keyPressed(KeyEvent e) {	
		if(KeyEvent.VK_RIGHT == e.getKeyCode()){
			if(e.isControlDown()){
				SetStockChartViewPortUtil.setStockChartViewPort((StockChartPanel)Global.get(UIChartingConstant.SelectedStockChartPanel));
			}else{
				SetStockChartViewPortUtil.setStockChartViewPort((StockChartPanel)Global.get(UIChartingConstant.SelectedStockChartPanel), e.isAltDown()?2:1);
			}
		}else if(KeyEvent.VK_LEFT == e.getKeyCode()){
			if(e.isControlDown()){
				SetStockChartViewPortUtil.setStockChartViewPort((StockChartPanel)Global.get(UIChartingConstant.SelectedStockChartPanel));
			}else{
				SetStockChartViewPortUtil.setStockChartViewPort((StockChartPanel)Global.get(UIChartingConstant.SelectedStockChartPanel), e.isAltDown()?-2:-1);
			}
		}
	}
	public void keyReleased(KeyEvent e) {	}
	public void mouseEntered(MouseEvent e) {
		Global.put(UIChartingConstant.SelectedStockChartPanel, e.getSource());
	}
	public void mouseExited(MouseEvent e) {}
	public void mouseReleased(MouseEvent e) {	}
	public void focusLost(FocusEvent e) {	}
}